package com.yt.lxh.common.exception;

import cn.hutool.core.util.StrUtil;
import com.yt.lxh.common.result.ResponseResult;
import com.yt.lxh.common.result.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@ControllerAdvice
@Slf4j
public class ExceptionCatch {

    /**
     * 处理不可控异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult exception(Exception e, HttpServletRequest request){
        log.error("异常信息：{}，请求地址：'{}'", e.getMessage(), request.getRequestURI());
        return ResponseResult.fail(ResultCodeEnum.SERVER_ERROR);
    }

    /**
     * 数据异常
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public ResponseResult httpMessageNotReadableExceptionCatch(HttpMessageNotReadableException e){
        log.error("数据异常：{}，", e.getMessage());
        return ResponseResult.fail(ResultCodeEnum.FAIL);
    }

    /**
     * 处理业务异常
     * @param e
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public ResponseResult exception(ServiceException e){
        log.info("异常信息：{}", e.getMessage() != null ? e.getMessage() : e.getErrCode().getMessage());
        return serviceResult(e);
    }

    /**
     * token 异常捕捉
     * @param e
     * @return
     */
    @ExceptionHandler(TokenException.class)
    @ResponseBody
    public ResponseResult tokenExceptionCatch(TokenException e){
        log.info("登录异常信息：{}", e.getMessage() != null ? e.getMessage() : e.getErrCode().getMessage());
        return serviceResult(e);
    }


    /**
     * 鹿雪禾执行异常
     * @param e
     * @return
     */
    @ExceptionHandler(LuXueHeException.class)
    @ResponseBody
    public ResponseResult LuXueHeExceptionCatch(LuXueHeException e) {
        log.error("异常：{}", e.getMessage());
        return ResponseResult.fail(e.getResultCodeEnum());
    }

    /**
     * SQL执行异常
     * @param e
     * @return
     */
    @ExceptionHandler(SqlHandlerException.class)
    @ResponseBody
    public ResponseResult SqlHandlerExceptionCatch(SqlHandlerException e) {
        log.error("SQL异常：{}", e.getMessage());
        return ResponseResult.fail(ResultCodeEnum.SERVER_ERROR);
    }

    /**
     * 实体类校验异常
     * @param e
     * @return
     */
    @ExceptionHandler({BindException.class, MethodArgumentNotValidException.class})
    @ResponseBody
    public ResponseResult bindExceptionHandler(MethodArgumentNotValidException e) {
        List<FieldError> errorList = e.getBindingResult().getFieldErrors();
        if (errorList.size() > 0) {
            String errMsg = errorList.get(errorList.size() - 1).getDefaultMessage();
            return ResponseResult.fail(ResultCodeEnum.PARAM_INVALID, errMsg);
        }
        return ResponseResult.fail(ResultCodeEnum.FAIL);
    }

    /**
     * 文件操作执行异常
     * @param e
     * @return
     */
    @ExceptionHandler(FileException.class)
    @ResponseBody
    public ResponseResult FileExceptionCatch(FileException e) {
//        log.error("File操作异常：{}", e.getMessage());
        return ResponseResult.fail(e.getErrCode());
    }

    // 失败结果消息的封装
    protected ResponseResult serviceResult(ServiceException e) {
        if (StrUtil.isEmpty(e.getMessage()))
            return ResponseResult.fail(e.getErrCode());
        else
            return ResponseResult.fail(e.getErrCode(), e.getMessage());
    }
}
